package com.wthink.hzgj.main

import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.speech.tts.TextToSpeech
import android.util.Log
import android.view.Gravity
import android.view.KeyEvent
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.Toast
import androidx.activity.viewModels
import androidx.annotation.IdRes
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import androidx.navigation.Navigation
import androidx.navigation.fragment.NavHostFragment
import com.wthink.card.Thread.PersecProcThread
import com.wthink.card.Thread.SerialFrameProcThread
import com.wthink.card.Thread.SocketFrameProcThread
import com.wthink.card.models.ShdFrameBundle
import com.wthink.hzgj.Constants
import com.wthink.hzgj.R
import com.wthink.hzgj.bus.PlanFragment
import com.wthink.hzgj.camera.CameraFragment
import com.wthink.hzgj.databinding.ActivityMainBinding
import com.wthink.hzgj.main.viewmodel.CheckinViewModel
import com.wthink.hzgj.main.viewmodel.MainViewModel
import com.wthink.hzgj.menu.MenuListFragment2
import com.wthink.hzgj.state.StateFragment
import com.wthink.hzgj.station.StationFragment
import com.wthink.hzgj.util.PreferencesUtils
import com.wthink.hzgj.util.`interface`.NoticeCallBack
import com.wthink.hzgj.util.setBackgroundAlpha
import java.io.File
import java.io.IOException
import java.nio.ByteBuffer
import java.util.*


import com.lenzshd.services.GPIOProc
import com.wthink.hzgj.util.CustomKeyEventProc


class MainActivity : AppCompatActivity(), TextToSpeech.OnInitListener {

    lateinit var binding: ActivityMainBinding
    private val viewModel by viewModels<MainViewModel>()
    private val checkinViewModel by viewModels<CheckinViewModel>()
    //val  thread = SerialFrameProcThread(this,uiHandler)
    var serialFrameProcThread: SerialFrameProcThread? = null
    var socketFrameProcThread: SocketFrameProcThread? = null
    var persecProcThread: PersecProcThread? = null
    var textToSpeech: TextToSpeech? = null

    var isMicIn: Int = -1

    private val checkinDialog by lazy {
        CheckinDialog.make(this, binding.root as ViewGroup, checkinViewModel, this)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        window.setFlags(
            WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
            WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
        )
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        binding.lifecycleOwner = this
        binding.viewModel = viewModel
        binding.checkinViewModel = checkinViewModel


        GPIOProc.AmplifierPw(1)
        GPIOProc.MicPw(1)

        PreferencesUtils.saveValue("isSelf", false)

        val nav = Navigation.findNavController(this, R.id.main)
        binding.topBar.setOnClickListener {
            nav.navTo(StateFragment::class.java, R.id.stateFragment)
        }

        binding.cameraSwitch.setOnClickListener {
            if (viewModel.cameraSwitchAndGet()) {
                nav.navTo(CameraFragment::class.java, R.id.cameraFragment)
            } else {
                nav.popBackStack()
            }
        }

        binding.checkin.setOnClickListener {
            checkinDialog.showAtLocation(
                binding.root,
                Gravity.CENTER,
                0,
                0
            )
            setBackgroundAlpha(0.6f)
        }

        viewModel.setCallBack(object : MainViewModel.ChangeMicCallBack {
            override fun callBack(type: Int) {
                if (type == 1) {
                    viewModel.changeMicModel(0)
                } else if (type == 0) {
                    viewModel.changeMicModel(1)
                }
            }
        })

        binding.micChange.setOnClickListener {
            when (isMicIn) {
                -1 -> {
                    isMicIn = 0
                    binding.micChange.text = "内置"
                    viewModel.closeMicCall(1)
                }

                0 -> {
                    isMicIn = 1
                    binding.micChange.text = "外置"
                    viewModel.closeMicCall(0)
                }
                1 -> {
                    isMicIn = -1
                    binding.micChange.text = "关闭"
                    viewModel.closeMic(1)
                }
            }
        }
    }

    private val uiHandler: Handler = object : Handler() {
        override fun handleMessage(msg: Message) {
            try {
                when (msg.what) {
                    Constants.UI_RC522 -> {
                        Log.d("TAGGGGGGG", "刷卡ID-->" + SocketFrameProcThread.mStrCardId)
                        if (checkinDialog.isShowing) {
                            binding.checkinViewModel?.userCode?.postValue(SocketFrameProcThread.mStrCardId.toString())
                        }
                        val frameBuf = ByteBuffer.allocate(20)
                        if (SocketFrameProcThread.mStrCardId != null) {
                            frameBuf.put(0x1b.toByte())
                            frameBuf.put(8.toByte())
                            frameBuf.put(SocketFrameProcThread.mStrCardId.toString().toByteArray())
                            frameBuf.put(0x1c.toByte())
                            frameBuf.put(0x00.toByte())
                        }
                    }
                    else -> super.handleMessage(msg)
                }
            } catch (e: Exception) {
                Log.d("AlbumsActivity", "Handler Exception ")
                e.printStackTrace()
            }
        }
    }

    override fun onResume() {
        super.onResume()
        if (textToSpeech == null) {
            textToSpeech = TextToSpeech(this, this)
        }

    }

    override fun onStart() {
        super.onStart()

        //  DpUtil.dateFormate("")

        viewModel.setNociceCallBack(object : NoticeCallBack {
            override fun noticeCall(info: String) {
                binding.scrollTextView.setContent(info)
                textToSpeech?.speak(info, TextToSpeech.QUEUE_FLUSH, null)
            }
        })

        //serialFrameProcThread = SerialFrameProcThread(this,uiHandler)
        //serialFrameProcThread!!.start()
        socketFrameProcThread = SocketFrameProcThread(this, uiHandler)
        socketFrameProcThread!!.start()
        persecProcThread =
            PersecProcThread(this, socketFrameProcThread, serialFrameProcThread, uiHandler)
        persecProcThread!!.start()

        val frameBuf = ByteBuffer.allocate(3)

        if (socketFrameProcThread != null) {
            frameBuf.clear()
            frameBuf.put(5.toByte())
            socketFrameProcThread!!.SendToMainBoardNormalFrm(
                ShdFrameBundle.B_SOCKET_FRAME_03,
                frameBuf.array(),
                1,
                ShdFrameBundle.A_SOCKET_MODEL_01
            )
        }

        viewModel.start()

        viewModel.waitBusDispatch {
            val boolean = PreferencesUtils.getBoolean("isSelf")
            if (!boolean) {
                val nav = Navigation.findNavController(this, R.id.main)
                val args = Bundle()
                args.putParcelable("dispatch", it)
                nav.navTo(PlanFragment::class.java, R.id.busPlanFragment, args)
            }
            PreferencesUtils.saveValue("isSelf", false)
        }

        viewModel.waitBusCameraCtl({
            if (!viewModel.isCameraShow()) {
                viewModel.cameraSwitchAndGet()
                val nav = Navigation.findNavController(this, R.id.main)
                nav.navTo(CameraFragment::class.java, R.id.cameraFragment)
            }
        }, {
            if (viewModel.isCameraShow()) {
                viewModel.cameraSwitchAndGet()
                val nav = Navigation.findNavController(this, R.id.main)
                nav.popBackStack()
            }
        })
    }

    fun <F : Fragment> NavController.navTo(
        fragmentClass: Class<F>, @IdRes resId: Int,
        args: Bundle? = null
    ) {
        val navHostFragment = supportFragmentManager.fragments.first() as NavHostFragment
        val fragments = navHostFragment.childFragmentManager.fragments

        if (fragments.isEmpty()) {
            navigate(R.id.stateFragment, args)
            return
        }

        if (fragmentClass.isAssignableFrom(fragments.first().javaClass)) {
            return
        }

        val find = fragments.find {
            fragmentClass.isAssignableFrom(it.javaClass)
        }

        if (find != null) {
            if (args != null) {
                throw IllegalStateException("not support backto and args not null")
            }
            popBackStack(resId, false)
        } else {
            navigate(resId, args)
        }
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        when (event?.scanCode) {
            Constants.KEYCODE_MENU -> {
                //跳转进入菜单界面
                val nav = Navigation.findNavController(this, R.id.main)
                nav.navTo(MenuListFragment2::class.java, R.id.menuListFragment2)
            }

            Constants.KEYCODE_PLAY, Constants.KEYCODE_REPLAY -> {
                val navHostFragment: NavHostFragment =
                    supportFragmentManager.fragments.first() as NavHostFragment
                val fragments: List<Fragment?> = navHostFragment.childFragmentManager.fragments
                for (fragment: Fragment? in fragments) {
                    if (fragment is StationFragment) {
                        val stationFragment: StationFragment = fragment as StationFragment
                        stationFragment.setkeyDown(event.scanCode)
                        break
                    }
                }
            }

            CustomKeyEventProc.KEY_F1 -> {
                viewModel.setVoice(6)
            }
            CustomKeyEventProc.KEY_F2 -> {
                viewModel.setVoice(1)
            }
            CustomKeyEventProc.KEY_F3 -> {
                viewModel.setVoice(2)
            }
            CustomKeyEventProc.KEY_F4 -> {
                viewModel.setVoice(3)
            }
            CustomKeyEventProc.KEY_F5 -> {
                viewModel.setVoice(4)
            }
            CustomKeyEventProc.KEY_F6 -> {
                viewModel.setVoice(5)
            }
            CustomKeyEventProc.KEY_F7 -> {
                viewModel.setVoice(6)
            }
            CustomKeyEventProc.KEY_F8 -> {
                viewModel.setVoice(7)
            }
            CustomKeyEventProc.KEY_F9 -> {
                viewModel.setVoice(8)
            }
            CustomKeyEventProc.KEY_F0 -> {
                viewModel.setVoice(9)
            }
        }
        return super.onKeyDown(keyCode, event)
    }

    override fun onDestroy() {
        if (serialFrameProcThread != null) {
            serialFrameProcThread!!.interrupt()
            try {
                serialFrameProcThread!!.join()
            } catch (e: InterruptedException) {
                e.printStackTrace()
            }
            serialFrameProcThread = null
        }
        if (socketFrameProcThread != null) {
            socketFrameProcThread!!.interrupt()
            try {
                socketFrameProcThread!!.join()
            } catch (e: InterruptedException) {
                e.printStackTrace()
            }
            socketFrameProcThread = null
        }

        if (persecProcThread != null) {
            persecProcThread!!.interrupt()
            try {
                persecProcThread!!.join()
            } catch (e: InterruptedException) {
                e.printStackTrace()
            }
            persecProcThread = null
        }
        super.onDestroy()
    }

    override fun onInit(status: Int) {
        val result = textToSpeech!!.setLanguage(Locale.CHINA)
        if (result == TextToSpeech.LANG_MISSING_DATA
            || result == TextToSpeech.LANG_NOT_SUPPORTED
        ) {
            Toast.makeText(this, "数据丢失或不支持", Toast.LENGTH_SHORT).show()
        }
    }

    private fun creatFile(path: String, `val`: String) {
        try {
            val file = File(path, `val`)
            if (!file.exists()) file.createNewFile()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }
}
